
const {
    Worker,
    MessageChannel,
    MessagePort,
    isMainThread,
    parentPort,
} = require("worker_threads");


if (isMainThread) {
	
var workerMutiThread = function(){
	var workerArr = [];
	var workerNum=0;
	var taskId=0;
	var taskArr = [];
	//const threads = new Set();
	
	//const threadCount = 2;
		  
    // uint8Arr 是放在共享内存上的
	
	//var sharedArray = new SharedArrayBuffer(Float32Array.BYTES_PER_ELEMENT * 4);
	//var float32Arr = new Float32Array(sharedArray);
	
		//console.log("[master] 原来的Arr", float32Arr);
		  
		  function addWorkerToNum(threadCount){

		  var worker,subChannel;
		  var workerAddNum=threadCount-workerNum;
		  var workerStartIndex=workerNum;
		  for (var i = workerStartIndex; i < threadCount; i++) {
			//console.time(`线程 ${i} 任务`);
			worker = new Worker(__filename, { workerData: { 
				//index:i,
				//projectPath:projectAbsolutePath,
				//functionName: functionName,
				//parameter: threads_parameter_arr[i],
				//config: config,
			}});
			
			//console.time(`线程 ${i} 添加进程`);
			//threads.add(worker);
			subChannel = new MessageChannel();
			//console.log(subChannel);
			workerArr.push({
				worker:worker,
				subChannel:subChannel,
			});
			workerArr[i].subChannel.port2.on("message", (data) => {
				var index = data.index;
				var taskId = data.taskId;
				taskArr[taskId]["workerDataArr"].push({
					index:index,
					data:data.data,
				});
				var threadCount = taskArr[taskId]["threadCount"];
				//全部完成了
				if(taskArr[taskId]["workerDataArr"].length==threadCount){
					//
					taskArr[taskId]["workerDataArr"].sort(function(a,b){
						return a.index-b.index;
					});
					var retArr = [];
					var workerDataArr = taskArr[taskId]["workerDataArr"];
					for(var i=0;i<workerDataArr.length;i++){
						retArr.push(workerDataArr[i].data);
					}
					
					//console.timeEnd(`线程总数: ${threadCount} 总计`);
					taskArr[taskId].callback.resolve(retArr);
				}
				//console.log(data);
				//console.log("[master] 经过工作线程修改的Arr", float32Arr);
				//workerArr[index].subChannel.port1.close();
				//workerArr[index].worker.terminate();//终止子进程
			});
			
				workerArr[i].worker.postMessage({ 
					workerInit: true,
					workerPort: workerArr[i].subChannel.port1,
					//data:{
					//	float32Arr:float32Arr
					//},
				}, [
					workerArr[i].subChannel.port1,
				]);
			
			workerNum++;
		  }
		  }
		  
		  function mutiThreadsDealing(projectAbsolutePath,functionName,threads_parameter_arr){
			  //console.log(projectAbsolutePath);
		return new Promise(function(resolve,reject){
			
			var info={
				projectPath:projectAbsolutePath,
				functionName:functionName,
				threads_parameter_arr:threads_parameter_arr,
			}
			//console.log(info);
			  var projectPath = info.projectPath;
			//console.log(projectPath);
			  
			  var threadCount = threads_parameter_arr.length;
			//console.time(`线程总数: ${threadCount} 总计`);
			  if(workerNum<threadCount){
				  addWorkerToNum(threadCount);
			  }
					
			//console.log(`Running with ${threadCount} threads...`);
			for (var i = 0; i < threadCount; i++) {
				workerArr[i].worker.postMessage({ 
					taskId:taskId,
					index:i,
					projectPath:projectPath,
					functionName: functionName,
					parameter: threads_parameter_arr[i],
					//data:{
					//	float32Arr:float32Arr
					//},
				});
			}
			taskArr.push({
				info:info,
				threadCount:threadCount,
				workerDataArr:[],
				callback:{
					resolve:resolve,
					reject:reject,
				},
			});
			taskId++;
			
			
			
		});
			
		  }
		  
		  
		//addWorkerToNum(1);
		//addWorkerToNum(2);
		//console.log(workerArr);
		/*
		(async () => {
			
			var projectAbsolutePath=__dirname+'/camera34523452/wordDealing0912364987.js';
			var functionName="getBinarySimilarity";
			var threads_parameter_arr=[
				{str1:[0.1,0.1],str2:[1,1]},
				{str1:[0.2,0.2],str2:[1,1]},
			];
			
			
			  var ret = await mutiThreadsDealing(projectAbsolutePath,functionName,threads_parameter_arr);
			console.log(ret);
		  
		})();
		*/
		  

	return{
		mutiThreadsDealing:mutiThreadsDealing,
	}
}();

if(typeof module != "undefined"){
	
	module.exports = workerMutiThread
}
		  

} else {
	
const assert = require("assert");
	// 获取函数的参数名
	function getParameterName(fn) {
		if(typeof fn !== 'object' && typeof fn !== 'function' ) return;
		const COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
		const DEFAULT_PARAMS = /=[^,)]+/mg;
		const FAT_ARROWS = /=>.*$/mg;
		let code = fn.prototype ? fn.prototype.constructor.toString() : fn.toString();
		code = code
			.replace(COMMENTS, '')
			.replace(FAT_ARROWS, '')
			.replace(DEFAULT_PARAMS, '');
		let result = code.slice(code.indexOf('(') + 1, code.indexOf(')')).match(/([^\s,]+)/g);
		return result === null ? [] :result;
	}
	
	
	var index;
	var workerPort;
	var projectObj = {};
	
    parentPort.on("message", async (data) => {
		if(data.workerInit){
			//console.log(data);
			assert(data.workerPort instanceof MessagePort);
			workerPort = data.workerPort;
			return;
		}
		index = data.index;
		
		var parameter = data.parameter;
		var taskId = data.taskId;
		
		
		
	var projectPath = data.projectPath;
	var functionName = data.functionName;
	var parameter = data.parameter;
	//var config=workerData.config;
//nodejs 客户端进程模式
					//console.time(`线程 ${index} 项目引入`);
					//console.log("projectPath:"+projectPath);
	if(!projectObj[projectPath]){
		projectObj[projectPath] = require(projectPath);
	}
	var project = projectObj[projectPath];
					//console.timeEnd(`线程 ${index} 项目引入`);
			if(!project){
				console.log(projectPath+"不存在")
			}else if(!project[functionName]){
				console.log(projectPath+"当中，functionName不存在:"+functionName)
			}else{
				
				var func = project[functionName];
				var funcParameterName = getParameterName(func);
				var parameterArr = [];
				for(var i=0;i<funcParameterName.length;i++){
					parameterArr.push(parameter[funcParameterName[i]]);
				}
				// console.log(parameterArr);
				var retData;
				//console.log(config);
				//if(config.not_async==true){
				//	retData = project[functionName](...parameterArr);
				//}else{
					//console.log(`线程 ${index} 开始计算`);
					
			
					//console.time(`线程 ${index} 数据计算`);
					retData = await project[functionName](...parameterArr);
					//console.timeEnd(`线程 ${index} 数据计算`);
				//}
				//console.time(`线程 ${index} 数据返回`);
				//parentPort.postMessage([index,retData]);
				workerPort.postMessage({index:index,taskId:taskId,data:retData});
				//console.timeEnd(`线程 ${index} 数据返回`);
				
			}
		
		
		
        //data.data.float32Arr[index] = index+1;
        //console.log("[worker]"+index+" 修改出来的Arr", data.data.float32Arr);
		//完成之后调用回调函数
        //workerPort.close();
    });
	/*
	setInterval(function(){
		console.log("[worker]"+index+" 定时任务");
        //workerPort.postMessage({index:index});
	},1000);
	*/
}
